/**
 * @file    gen_halfedge.h
 * @author  fynkxo (fynkxo@domain.com)
 * @brief   The generator, generates single halfe-edge polygon.
 * @version 0.1
 * @date    2025-08-10
 *
 * @copyright Copyright (c) 2025 fynkxo
 *
 */

#ifndef GEN_HALFEDGE_H
#define GEN_HALFEDGE_H 1

#include "cgal_defines.hpp"

#include <stdexcept>
#include <vector>

namespace cgalView {

class gen_halfedge {
public:
  /**
   * @brief Construct a new gen halfedge object.
   *
   * @param offset Specify the offset value that the half-edge is offset.
   * @param len_arrow Specify the length value of the arrow.
   */
  gen_halfedge(double offset = 0.01, double len_arrow = 0.01,
               int angle_arrow = 45)
      : d_halfedge_offset(offset), d_length_arrow(len_arrow),
        d_angle_arrow(angle_arrow) {
    if (d_halfedge_offset < 0 || d_length_arrow <= 0) {
      throw std::invalid_argument{"Invalid argument, requires greate 0."};
    }
    set_angle_arrow(angle_arrow);
  }

  gen_halfedge(gen_halfedge const &) noexcept = default;
  gen_halfedge(gen_halfedge &&) noexcept = default;
  gen_halfedge &operator=(gen_halfedge const &) noexcept = default;
  gen_halfedge &operator=(gen_halfedge &&) noexcept = default;

  /**
   * @brief Get the halfedge offset value.
   *
   * @return double
   */
  double get_halfedge_offset() const noexcept { return d_halfedge_offset; }

  /**
   * @brief Set the halfedge offset value.
   *
   * @param offset
   * @exception invalid_argument
   */
  void set_halfedge_offset(double offset) {
    if (offset < 0) {
      throw std::invalid_argument{"The value greate 0 is required."};
    }
    this->d_halfedge_offset = offset;
  }

  /**
   * @brief Get the length arrow value.
   *
   * @return double
   */
  double get_length_arrow() const noexcept { return this->d_length_arrow; }

  /**
   * @brief Set the length arrow value.
   *
   * @param len
   * @exception invalid_argument
   */
  void set_length_arrow(double len) {
    if (len <= 0) {
      throw std::invalid_argument{"The value must be greate 0."};
    }
    this->d_length_arrow = len;
    std::cout << __FUNCTION__ << ": Len -> " << this->d_length_arrow;
  }

  /**
   * @brief Get the angle arrow value.
   *
   * @return double
   */
  double get_angle_arrow() const noexcept { return this->d_angle_arrow; }

  /**
   * @brief Set the angle arrow value.
   *
   * @param angle
   * @exception invalid_argument
   */
  void set_angle_arrow(int angle) {
    if (angle < 10 || angle > 80) {
      throw std::invalid_argument("require in range [10, 80].");
    }
    this->d_angle_arrow = angle;
  }

  /**
   * @brief Generate.
   *
   * @param start The start of edge.
   * @param end The end of edge.
   * @return std::vector<point_type>
   */
  std::vector<point_type> gen(point_type const &start, point_type const &end,
                              vector_type const &normal_face);

private:
  double d_halfedge_offset;
  double d_length_arrow;
  int d_angle_arrow;
};
} // namespace cgalView
#endif // GEN_HALFEDGE_H